/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

// THIS FILE IS GENERATED BY ZAP

#include <app/data-model/Decode.h>
#include <app/data-model/Encode.h>

#pragma once

namespace chip {

struct PairWithCodeCommand
{
    chip::NodeId nodeId;
    chip::CharSpan payload;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), payload));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, payload));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct UnpairCommand
{
    chip::NodeId nodeId;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct GetCommissionerNodeIdCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct GetCommissionerNodeIdResponse
{
    chip::NodeId nodeId;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForMsCommand
{
    uint32_t ms;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), ms));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, ms));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForCommissioningCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForCommissioneeCommand
{
    chip::NodeId nodeId;
    Optional<bool> expireExistingSession;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), expireExistingSession));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, expireExistingSession));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForMessageCommand
{
    Optional<chip::CharSpan> registerKey;
    chip::CharSpan message;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), message));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, message));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByShortDiscriminatorCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByLongDiscriminatorCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByCommissioningModeCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByVendorIdCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByDeviceTypeCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByNameCommand
{
    chip::CharSpan value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionerCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionerByVendorIdCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionerByDeviceTypeCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct DiscoveryCommandResponse
{
    chip::CharSpan hostName;
    chip::CharSpan instanceName;
    uint16_t longDiscriminator;
    uint8_t shortDiscriminator;
    uint16_t vendorId;
    uint16_t productId;
    uint8_t commissioningMode;
    uint16_t deviceType;
    chip::CharSpan deviceName;
    chip::ByteSpan rotatingId;
    uint64_t rotatingIdLen;
    uint16_t pairingHint;
    chip::CharSpan pairingInstruction;
    bool supportsTcp;
    uint8_t numIPs;
    uint16_t port;
    Optional<uint32_t> mrpRetryIntervalIdle;
    Optional<uint32_t> mrpRetryIntervalActive;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), hostName));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), instanceName));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(2), longDiscriminator));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(3), shortDiscriminator));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(4), vendorId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(5), productId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(6), commissioningMode));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(7), deviceType));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(8), deviceName));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(9), rotatingId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(10), rotatingIdLen));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(11), pairingHint));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(12), pairingInstruction));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(13), supportsTcp));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(14), numIPs));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(15), port));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(16), mrpRetryIntervalIdle));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(17), mrpRetryIntervalActive));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, hostName));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, instanceName));
                break;
            case 2:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, longDiscriminator));
                break;
            case 3:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, shortDiscriminator));
                break;
            case 4:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, vendorId));
                break;
            case 5:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, productId));
                break;
            case 6:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, commissioningMode));
                break;
            case 7:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, deviceType));
                break;
            case 8:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, deviceName));
                break;
            case 9:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rotatingId));
                break;
            case 10:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rotatingIdLen));
                break;
            case 11:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, pairingHint));
                break;
            case 12:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, pairingInstruction));
                break;
            case 13:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, supportsTcp));
                break;
            case 14:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, numIPs));
                break;
            case 15:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, port));
                break;
            case 16:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, mrpRetryIntervalIdle));
                break;
            case 17:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, mrpRetryIntervalActive));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct LogCommand
{
    chip::CharSpan message;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), message));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, message));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct UserPromptCommand
{
    chip::CharSpan message;
    Optional<chip::CharSpan> expectedValue;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), message));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), expectedValue));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, message));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, expectedValue));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct StartCommand
{
    Optional<chip::CharSpan> registerKey;
    Optional<uint16_t> discriminator;
    Optional<uint16_t> port;
    Optional<chip::CharSpan> kvs;
    Optional<uint16_t> minCommissioningTimeout;
    Optional<chip::CharSpan> filepath;
    Optional<chip::CharSpan> otaDownloadPath;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), discriminator));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(2), port));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(3), kvs));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(4), minCommissioningTimeout));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(5), filepath));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(6), otaDownloadPath));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, discriminator));
                break;
            case 2:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, port));
                break;
            case 3:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, kvs));
                break;
            case 4:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, minCommissioningTimeout));
                break;
            case 5:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, filepath));
                break;
            case 6:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, otaDownloadPath));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct StopCommand
{
    Optional<chip::CharSpan> registerKey;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct RebootCommand
{
    Optional<chip::CharSpan> registerKey;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FactoryResetCommand
{
    Optional<chip::CharSpan> registerKey;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct CreateOtaImageCommand
{
    chip::CharSpan otaImageFilePath;
    chip::CharSpan rawImageFilePath;
    chip::CharSpan rawImageContent;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), otaImageFilePath));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), rawImageFilePath));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(2), rawImageContent));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, otaImageFilePath));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rawImageFilePath));
                break;
            case 2:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rawImageContent));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct CompareFilesCommand
{
    chip::CharSpan file1;
    chip::CharSpan file2;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), file1));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), file2));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, file1));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, file2));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

namespace app {
namespace Clusters {

namespace CommissionerCommands {
namespace Commands {
namespace PairWithCode {
using Type = struct PairWithCodeCommand;
}
namespace Unpair {
using Type = struct UnpairCommand;
}
namespace GetCommissionerNodeId {
using Type = struct GetCommissionerNodeIdCommand;
}
namespace GetCommissionerNodeIdResponse {
using DecodableType = struct GetCommissionerNodeIdResponse;
}
} // namespace Commands
} // namespace CommissionerCommands

namespace DelayCommands {
namespace Commands {
namespace WaitForMs {
using Type = struct WaitForMsCommand;
}
namespace WaitForCommissioning {
using Type = struct WaitForCommissioningCommand;
}
namespace WaitForCommissionee {
using Type = struct WaitForCommissioneeCommand;
}
namespace WaitForMessage {
using Type = struct WaitForMessageCommand;
}
} // namespace Commands
} // namespace DelayCommands

namespace DiscoveryCommands {
namespace Commands {
namespace FindCommissionable {
using Type = struct FindCommissionableCommand;
}
namespace FindCommissionableByShortDiscriminator {
using Type = struct FindCommissionableByShortDiscriminatorCommand;
}
namespace FindCommissionableByLongDiscriminator {
using Type = struct FindCommissionableByLongDiscriminatorCommand;
}
namespace FindCommissionableByCommissioningMode {
using Type = struct FindCommissionableByCommissioningModeCommand;
}
namespace FindCommissionableByVendorId {
using Type = struct FindCommissionableByVendorIdCommand;
}
namespace FindCommissionableByDeviceType {
using Type = struct FindCommissionableByDeviceTypeCommand;
}
namespace FindCommissionableByName {
using Type = struct FindCommissionableByNameCommand;
}
namespace FindCommissioner {
using Type = struct FindCommissionerCommand;
}
namespace FindCommissionerByVendorId {
using Type = struct FindCommissionerByVendorIdCommand;
}
namespace FindCommissionerByDeviceType {
using Type = struct FindCommissionerByDeviceTypeCommand;
}
namespace DiscoveryCommandResponse {
using DecodableType = struct DiscoveryCommandResponse;
}
} // namespace Commands
} // namespace DiscoveryCommands

namespace LogCommands {
namespace Commands {
namespace Log {
using Type = struct LogCommand;
}
namespace UserPrompt {
using Type = struct UserPromptCommand;
}
} // namespace Commands
} // namespace LogCommands

namespace SystemCommands {
namespace Commands {
namespace Start {
using Type = struct StartCommand;
}
namespace Stop {
using Type = struct StopCommand;
}
namespace Reboot {
using Type = struct RebootCommand;
}
namespace FactoryReset {
using Type = struct FactoryResetCommand;
}
namespace CreateOtaImage {
using Type = struct CreateOtaImageCommand;
}
namespace CompareFiles {
using Type = struct CompareFilesCommand;
}
} // namespace Commands
} // namespace SystemCommands

} // namespace Clusters
} // namespace app

} // namespace chip
